package com.spa.infrastructure.exception;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.SaTokenException;
import com.spa.infrastructure.common.CommonCode;
import com.spa.infrastructure.common.ResponseHelper;
import com.spa.infrastructure.common.ResponseMessage;
import com.spa.infrastructure.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * 全局异常处理器
 *
 * @author spa
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @Autowired
    private ResponseHelper<Void> responseHelper;

    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResponseMessage<Void> handlerException(Exception e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生系统异常." , requestURI, e);
        return fail(CommonCode.FAIL.getCode(), e.getMessage());
    }


    @ResponseBody
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseMessage<Void> handleRuntimeException(RuntimeException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生未知异常." , requestURI, e);
        //2024-02-05 lig add 解决hutool Assert 异常信息错误
        if(e.getCause() instanceof IllegalArgumentException ill){
            return fail(CommonCode.FAIL.getCode(), ill.getMessage());
        }
        return fail(CommonCode.FAIL.getCode(), e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = SpaException.class)
    public ResponseMessage<Void> handlerSpaException(SpaException e , HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',发生自定义异常." , requestURI, e);
        if(StringUtils.isNotEmpty(e.getCode())){
            return fail(e.getCode(), e.getMessage());
        }
        return fail(CommonCode.FAIL.getCode(), e.getMessage());
    }




//    public ResponseMessage<Void> fail(String code, String message, Exception e) {
//        log.error("Exception : ", e);
//        return responseHelper.createFailMessage(code, message);
//    }

    public ResponseMessage<Void> fail(String code, String message) {
        return responseHelper.createFailMessage(code, message);
    }

    /**
     * sa-token 异常处理
     */
    @ExceptionHandler(SaTokenException.class)
    public ResponseMessage<Void> handlerSaTokenException(SaTokenException e, HttpServletRequest request) {

        String requestURI = request.getRequestURI();
        if(e instanceof NotLoginException){
            log.error("请求地址'{}',未登录'{}'" , requestURI, e.getMessage());
        }
        if(e instanceof NotPermissionException){
            log.error("请求地址'{}',权限校验失败'{}'" , requestURI, e.getMessage());
        }
        return fail(CommonCode.UN_LOGIN.getCode(), "未登录");

    }

    /**
     * 处理@NotNull 注解返回
     *
     * @author: lig
     * @date: 2024/1/16
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseMessage<Void> handlerMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',注解返回异常处理'{}'" , requestURI, e.getMessage());
        StringBuilder sb = new StringBuilder();
        e.getBindingResult().getAllErrors().forEach(objectError -> {
            sb.append(objectError.getDefaultMessage());
            sb.append("!");
        });
        return fail(CommonCode.FAIL.getCode(), sb.toString());
    }

}
